package edu.gatech.spacetraderteam3.model;

import java.awt.Color;
import java.io.Serializable;
import java.util.Arrays;

import edu.gatech.spacetraderteam3.debug.Debug;
import edu.gatech.spacetraderteam3.view.Assets;

/**
 * Solar System class. Has many properties and list of planets. 
 * @author TBW
 * @version 1.0
 */
public class SpaceSolarSystem implements Serializable {
    /**
     * The serial verision UID for this solar system (used in saving)
     */
    private static final long serialVersionUID = -6205451436532829220L;

    /**
     * The name of the solar system
     */
    private String name;

    /**
     * The planets in this solar system
     */
    private final SpacePlanet[] planets;

    /**
     * The system's sun icon
     */
    private final Assets.SunIcon sun;

    /**
     * the system's color on the galaxy view
     */
    private final Color color;

    /**
     * The system's state of being
     */
    private State systemState;

    /**
     * The placement of the system relative to center of galaxy
     */
    private final double theta, radius;

    /**
     * Constructor for prefab Solar Systems. 
     * @param prefab The prefabricated solar system
     */
    public SpaceSolarSystem(SSPrefab prefab) {
        this.name = prefab.name();
        this.sun = prefab.sun();
        this.planets = prefab.planets();
        this.color = prefab.color();
        this.radius = prefab.radius();
        this.theta = prefab.theta();
        this.systemState = State.random();
        Debug.write("Solar system \"" + String.format("%-12s", name)
                + "\" created with theta " + theta + " and radius " + radius + ".", 1);
        for (SpacePlanet p : planets) {
            Debug.write("\tPlanet created: " + p.toString(), 1);
            p.setSystem(this);
        }
    }

    /**
     * Constructor for the solar system
     * @param sun Sun icon
     * @param color Color of the system
     * @param radius Radius of the system
     * @param theta Angle of the system
     * @param planets Planets within the system
     */
    public SpaceSolarSystem(Assets.SunIcon sun, Color color, double radius, double theta,
            SpacePlanet... planets) {
        this.sun = sun;
        this.color = color;
        this.radius = radius;
        this.theta = theta;
        this.systemState = State.random();
        this.planets = new SpacePlanet[planets.length];
        System.arraycopy(planets, 0, this.planets, 0, planets.length);
    }

    /**
     * Getter for the system name
     * @return the system name
     */
    public String getName() {
        return name.charAt(0) + name.substring(1).toLowerCase();
    }

    /**
     * Getter for the sun icon
     * @return The sun icon
     */
    public Assets.SunIcon getSun() {
        return sun;
    }

    /**
     * Getter for the planets in the solar system
     * @return the planets
     */
    public SpacePlanet[] getPlanets() {
        return planets;
    }

    /**
     * Getter for the State of the system
     * @return the state of the system
     */
    public State getState() {
        return systemState;
    }

    /**
     * Generates a random state for the solar system
     */
    public void randomState() {
        this.systemState = State.random();
    }

    /**
     * Getter the orbiting radius of the solar system
     * @return The orbiting radius
     */
    public double getOrbitingRadius() {
        return radius;
    }

    /**
     * Getter for the orbiting angle
     * @return The angle 
     */
    public double getOrbitingAngle() {
        return theta;
    }

    /**
     * Getter for the system color
     * @return the color
     */
    public Color getColor() {
        return color;
    }

    /**
     * Calculates the distance between this solar system and another one
     * @param other The other solar system to calculate distance between
     * @return The distance. 
     */
    public double distanceTo(SpaceSolarSystem other) {
        final double x = radius * Math.cos(theta);
        final double x2 = other.radius * Math.cos(other.theta);

        final double y = radius * Math.sin(theta);
        final double y2 = other.radius * Math.sin(other.theta);
        final double dist = Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y - y2, 2));
        Debug.write("Distance from " + name + " to " + other.name + ": " + dist, 2);
        return dist;
    }

    /**
     * @return the string representation of this solarsystem
     */
    public String toString() {
        return "Solar System: " + Arrays.toString(planets);
    }
}
